import { Injectable } from '@nestjs/common';
import { Product_Create_Dto, Product_Update_Dto } from './assets/product.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Product } from './assets/product.entity';
import { Repository } from 'typeorm';
import { Product_Find_Dto, Product_FindAll_Dto } from './assets/product.dto';
import {
  util_Db_PageList,
  util_Db_NoPageList,
  util_Db_Delete,
  util_Db_Update,
  util_Db_Add,
} from '@/common/util/db';
import { Spec } from '../spec/assets/spec.entity';
import { Platform } from '../platform/assets/platform.entity';
import { SpecsType } from '../specsType/assets/specsType.entity';

@Injectable()
export class Product_Service {
  constructor(
    @InjectRepository(Product)
    private product_Repository: Repository<Product>,
    @InjectRepository(Spec)
    private spce_Repository: Repository<Spec>,
    @InjectRepository(SpecsType)
    private spcesType_Repository: Repository<SpecsType>,
    @InjectRepository(Platform)
    private platform_Repository: Repository<Platform>,
  ) {}

  async product_Create(body: Product_Create_Dto) {
    const specs = [];
    const specsType = [];
    body.specs.map((item) => {
      specs.push(this.spce_Repository.create({ id: item }));
    });
    body.specs = specs;
    body.specsType.map((item) => {
      specsType.push(this.spcesType_Repository.create({ id: item }));
    });
    body.specsType = specsType;
    const platform = this.platform_Repository.create({
      id: body.platformId,
    });
    return await util_Db_Add({
      createDto: { ...body, platform: platform },
      repository: this.product_Repository,
    });
  }

  async product_ProductsWeb(id: number) {
    return {
      list: await this.product_Repository
        .createQueryBuilder('product')
        .leftJoinAndSelect('product.specs', 'specs')
        .leftJoinAndSelect('specs.specsType', 'spspType')
        .andWhere(`product.platformId = :platformId`, { platformId: id })
        .getMany(),
      ...(await this.platform_Repository
        .createQueryBuilder('platform')
        .andWhere(`id = :id`, { id })
        .getOne()),
    };
  }

  async product_FindByPage(query: Product_Find_Dto) {
    const { size, page, platformId } = query;
    const queryBuilder = this.product_Repository
      .createQueryBuilder('product')
      .leftJoinAndSelect('product.specs', 'specs')
      .leftJoinAndSelect('product.platform', 'platform');
    return await util_Db_PageList<Product>({
      queryBuilder,
      query: { 'platform.id': platformId, page, size },
    });
  }

  async product_FindAllSelect(query: Product_FindAll_Dto) {
    return await util_Db_NoPageList<Product>({
      queryBuilder: this.product_Repository
        .createQueryBuilder('product')
        .select(['product.id AS id', 'product.productName AS name']),
      query: { 'product.platformId': query.platformId },
      isRaw: true,
    });
  }

  async product_Update(body: Product_Update_Dto) {
    return await util_Db_Update({
      findOne: () => this.productFindOneById(body.id),
      updateDto: body,
      repository: this.product_Repository,
    });
  }

  async product_Remove(id: number) {
    return await util_Db_Delete({
      findOne: () => this.productFindOneById(id),
      id,
      repository: this.product_Repository,
    });
  }

  async productFindOneById(id: number) {
    return await this.product_Repository
      .createQueryBuilder('product')
      .andWhere(`product.id = :id`, { id: id })
      .getOne();
  }

  async product_ProductPlatformWeb(id: number) {
    return await this.product_Repository
      .createQueryBuilder('product')
      .leftJoin('product.platform', 'platform')
      .andWhere(`product.id = :id`, { id: id })
      .select([
        'product.productName AS productName',
        'product.productAtention AS productAtention',
        'product.productPrice AS productPrice',
        'product.productTime AS productTime',
        'product.productNum AS productNum',
        'product.productName AS productName',
        'platform.platFormName AS platFormName',
        'product.productImg AS productImg',
      ])
      .getRawOne();
  }
}
